module synop_mongo_mod

  use iso_c_binding
  use mongof_common_mod
  use datetime
  use string
  use container
  use flogger
  use params_mod
  use data_translators_utils_mod
  use synop_mod

  implicit none

  private

  public synop_mongo_write

  interface
    integer function synop_mongoc_insert_platform(cid, name, lon, lat, alt) result(res) bind(c, name='synop_mongoc_insert_platform')
      use iso_c_binding
      integer(c_int), intent(in) :: cid
      character(c_char), intent(in) :: name
      real(c_float), intent(in) :: lon
      real(c_float), intent(in) :: lat
      real(c_float), intent(in) :: alt
    end function synop_mongoc_insert_platform

    integer function synop_mongoc_insert_record(cid, name, timestamp, ta, p, rh, sh, ua, va, ws, wd) result(res) bind(c, name='synop_mongoc_insert_record')
      use iso_c_binding
      integer(c_int), intent(in) :: cid
      character(c_char), intent(in) :: name
      real(c_double), intent(in) :: timestamp
      real(c_float), intent(in) :: ta
      real(c_float), intent(in) :: p
      real(c_float), intent(in) :: rh
      real(c_float), intent(in) :: sh
      real(c_float), intent(in) :: ua
      real(c_float), intent(in) :: va
      real(c_float), intent(in) :: ws
      real(c_float), intent(in) :: wd
    end function synop_mongoc_insert_record
  end interface

contains

  subroutine synop_mongo_write(mongo_uri, mongo_db, mongo_col, stations, records)

    character(*), intent(in) :: mongo_uri
    character(*), intent(in) :: mongo_db
    character(*), intent(in) :: mongo_col
    type(hash_table_type), intent(in) :: stations
    type(linked_list_type), intent(in) :: records

    integer(c_int) cid_station, cid_record
    character(10) sid
    type(linked_list_iterator_type) it

    call mongoc_init()

    call handle_mongo_error(mongoc_connect('mongodb://' // trim(mongo_uri) // char(0), trim(mongo_db) // char(0), &
      trim(mongo_col) // '_stations' // char(0), cid_station), __FILE__, __LINE__)

    call handle_mongo_error(mongoc_connect('mongodb://' // trim(mongo_uri) // char(0), trim(mongo_db) // char(0), &
      trim(mongo_col) // '_records' // char(0), cid_record), __FILE__, __LINE__)

    call handle_mongo_error(mongoc_create_platform_index(cid_station), __FILE__, __LINE__)
    call handle_mongo_error(mongoc_create_record_index(cid_record), __FILE__, __LINE__)

    it = linked_list_iterator(records)
    do while (.not. it%ended())
      select type (record => it%value)
      type is (synop_record_type)
        sid = trim(record%station%name) // char(0)
        call handle_mongo_error(synop_mongoc_insert_platform(cid_station, sid, &
          record%station%lon, record%station%lat, record%station%z), __FILE__, __LINE__)
        call handle_mongo_error(synop_mongoc_insert_record(cid_record, sid, &
          record%time%timestamp(), record%ta, record%p, record%rh, record%sh, record%ua, record%va, record%ws, record%wd), __FILE__, __LINE__)
      end select
      call it%next()
    end do

    call mongoc_final()

  end subroutine synop_mongo_write

end module synop_mongo_mod
